package com.ziytek.web.citizen.caffeine;

import com.github.benmanes.caffeine.cache.Cache;
import com.ziytek.web.citizen.constant.NumConstant;
import com.ziytek.web.citizen.constant.ServerConstant;
import com.ziytek.web.citizen.enums.ControlVersionEnum;
import com.ziytek.web.citizen.enums.PositionEnum;
import com.ziytek.web.citizen.enums.PositionNumEnum;
import com.ziytek.web.citizen.util.CabinetNoUtil;
import com.ziytek.web.citizen.util.StringUtil;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
 * @author fengh
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class PositionCacheConfig {

    private final Cache<String, Object> caffeinePositionCache;
    private final Cache<String, Object> caffeinePositionNoCache;
    private final Cache<String, Integer> caffeinePositionSeqCache;
    private final Cache<String, Object> caffeinePositionLineCodeCache;
    private final Cache<String, Integer> caffeinePositionControlCache;
    private final Cache<String, Object> caffeinePositionSeqValueCache;


    private static final List<String> INIT_VALUE_LIST = new ArrayList<>();

    @PostConstruct
    public void positionInit() {
        log.info("PositionCacheConfig init success start");

        for (PositionEnum p : PositionEnum.values()) {
            caffeinePositionCache.put(p.getCode(), p.getDesc() + ServerConstant.DATA_SEPARATOR + p.getPosition());
            caffeinePositionLineCodeCache.put(p.getDesc() + ServerConstant.DATA_SEPARATOR + p.getPosition(), p.getCode());
        }

        for (ControlVersionEnum p : ControlVersionEnum.values()) {
            caffeinePositionControlCache.put(p.getCode(), p.getPosition());
        }

        for (PositionNumEnum p : PositionNumEnum.values()) {
            caffeinePositionSeqCache.put(p.getCode(), p.getSeq());
            caffeinePositionSeqValueCache.put(p.getCode(), p.getDesc() + ServerConstant.DATA_SEPARATOR_LIND + p.getCode().split(ServerConstant.DATA_SEPARATOR_LIND)[NumConstant.INT_ONE]);
        }

        log.info("PositionCacheConfig init success");
        initInitValueList();
    }

    public String getLineCode(String key) {
        return Optional.ofNullable((String) caffeinePositionLineCodeCache.getIfPresent(key)).orElse("");
    }

    public int getControlPosition(String code) {
        return Optional.ofNullable(caffeinePositionControlCache.getIfPresent(code)).orElse(NumConstant.INT_ZERO);
    }

    public String getLinePositionByCode(String code) {
        return Optional.ofNullable((String) caffeinePositionCache.getIfPresent(code)).orElse("0,0");
    }

    public String getLinePosition(String code) {
        return Optional.ofNullable((String) caffeinePositionCache.getIfPresent(code)).orElse("0,0");
    }


    private void initInitValueList() {
        List<String> keySet = caffeinePositionLineCodeCache.asMap().keySet().stream().toList();
        if (CollectionUtils.isEmpty(keySet)) {
            log.info("分容柜电池行序列基础数据为空，请检查数据,keySet is null");
            return;
        }

        INIT_VALUE_LIST.clear();
        keySet.forEach(k -> INIT_VALUE_LIST.add(ServerConstant.DATA_SEPARATOR.concat(k)));
        log.info("Initialize the basic data of the battery row sequence in the capacity divider cabinet successfully:{}", INIT_VALUE_LIST.size());
    }


    public List<String> getValueListByCabinetNo(String cabinetNo) {
        if (StringUtil.isEmpty(cabinetNo)) {
            return Collections.emptyList();
        }

        cabinetNo = CabinetNoUtil.getCabinetNo(cabinetNo);
        List<String> initValueList = new ArrayList<>();
        for (String s : INIT_VALUE_LIST) {
            initValueList.add(cabinetNo.concat(s));
        }
        return initValueList;
    }

    public int getPositionSeq(String code) {
        String key = (String) caffeinePositionLineCodeCache.getIfPresent(code);
        if (StringUtils.isNotEmpty(key)) {
            return Optional.ofNullable(caffeinePositionSeqCache.getIfPresent(key)).orElse(NumConstant.INT_ZERO);
        }
        return NumConstant.INT_ZERO;
    }


    public String getPositionSeqValue(String code) {

        String key = (String) caffeinePositionLineCodeCache.getIfPresent(code);
        if (StringUtils.isNotEmpty(key)) {
            return Optional.ofNullable((String) caffeinePositionSeqValueCache.getIfPresent(key)).orElse(code);
        }

        return code;
    }

    public void setLineByCode(String code, String line) {
        caffeinePositionNoCache.put(code, line);
    }


    public String getLineByCode(String code) {
        Object line = caffeinePositionNoCache.getIfPresent(code);
        return line == null ? "" : (String) line;
    }

    public int getPositionByCode(String code, int num) {
        Object line = caffeinePositionNoCache.getIfPresent(code + "-" + num);
        return line == null ? -1 : (Integer) line;
    }

    public void setPositionByCode(String code, int num, int position) {
        caffeinePositionNoCache.put(code + "-" + num, position);
    }

}